package xyz.yq56.easytool.utils.nvll;

import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * 空值处理工具类
 * <br> 目标是跟null有关的处理，这里都能有，加油
 * <br> 默认返回空对象
 *
 * @author yi qiang
 * @date 2021/9/17 0:32
 */
public class NullUtil {

    private NullUtil() {
    }

    /**
     * 如果字符串为空值或者null,那么返回空值
     *
     * @param str 字符串
     * @return 不会为null
     */
    public static String emptyIfNull(String str) {
        return StringUtils.isEmpty(str) ? "" : str;
    }

    /**
     * 如果集合为空值或者null,那么返回空集合
     *
     * @param list 集合
     * @return 不会为null
     */
    public static <T> List<T> emptyIfNull(List<T> list) {
        return CollectionUtils.isEmpty(list) ? Collections.emptyList() : list;
    }

    /**
     * 如果集合为空值或者null,那么返回空集合
     *
     * @param set 集合
     * @return 不会为null
     */
    public static <T> Set<T> emptyIfNull(Set<T> set) {
        return CollectionUtils.isEmpty(set) ? Collections.emptySet() : set;
    }

    /**
     * 如果集合为空值或者null,那么返回空集合
     *
     * @param map 集合
     * @return 不会为null
     */
    public static <K, V> Map<K, V> emptyIfNull(Map<K, V> map) {
        return CollectionUtils.isEmpty(map) ? Collections.emptyMap() : map;
    }

    /**
     * 执行function,t为null则返回null
     *
     * @param t        主体
     * @param function 函数
     * @param <T>      入参
     * @param <R>      结果
     * @return 执行结果
     */
    public static <T, R> R apply(T t, Function<T, R> function) {
        return t == null ? null : function.apply(t);
    }

    /**
     * t为null则返回null
     * u为null执行第一种情况，u不为null执行第二种情况
     *
     * @param t        主体
     * @param function 函数
     * @param <T>      入参
     * @param <R>      结果
     * @return 执行结果
     */
    public static <T, U, R> R apply(T t, U u, Function<T, R> function, BiFunction<T, U, R> biFunction) {
        if (t == null) {
            return null;
        }
        return u == null ? function.apply(t) : biFunction.apply(t, u);
    }

    /**
     * 返回当前对象是否为空
     *
     * @param obj 对象
     * @return 是否为空
     */
    public static boolean isNull(Object obj) {
        return obj == null;
    }

    /**
     * 只要有一个为null，那就返回true
     *
     * @param objs objs 待判断集合
     * @return 是否为null
     */
    public static boolean isAndNull(Object... objs) {
        //只要有一个为null，那就为true
        for (Object obj : objs) {
            if (obj == null) {
                return true;
            }
        }
        return false;
    }

    /**
     * 只要有一个不为null，那就返回false
     *
     * @param objs 待判断集合
     * @return 是否为null
     */
    public static boolean isOrNull(Object... objs) {
        for (Object obj : objs) {
            if (obj != null) {
                return false;
            }
        }
        return true;
    }

    /**
     * 返回当前集合类是否为空
     *
     * @param collection 集合类
     * @return 集合类
     */
    public static boolean isEmpty(Collection<?> collection) {
        return CollectionUtils.isEmpty(collection);
    }

    /**
     * 返回当前Map是否为空
     *
     * @param map map
     * @return 是否为空
     */
    public static boolean isEmpty(Map<?, ?> map) {
        return CollectionUtils.isEmpty(map);
    }

    /**
     * 返回当前数组是否为空
     *
     * @param array 数组
     * @return 是否为空
     */
    public static boolean isEmpty(Object[] array) {
        return ArrayUtils.isEmpty(array);
    }


    public static <E, U> Optional<U> map(E e, Function<? super E, ? extends U> mapper) {
        return Optional.ofNullable(e).map(mapper);
    }

    public static <E, U> U map(E e, Function<? super E, U> mapper, U defaultValue) {
        return map(e, mapper).orElse(defaultValue);
    }

    public static void main(String[] args) {
        System.out.println(NullUtil.map(null, item -> new Date(), 4));
    }

}
